package create.factory.factory_demo2;

import create.factory.factory_demo1.Shape;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

/**
 * 动态工厂，使用反射解决了第一种工厂里增加类型需要改ShapeFactory中代码
 *
 * @author yeyangtao created at 15:56 2020/11/5
 */
public class ShapeFactory2 implements FactoryMethod {
    Map<String, Constructor<?>> factories = new HashMap<>();

    static Constructor<?> load(String id) {
        System.out.println("loading:" + id);
        try {
            return Class.forName("create.factory.factory_demo1." + id)
                    .getConstructor();
        } catch (Exception e) {
            throw new RuntimeException("加载对象失败");
        }
    }

    @Override
    public Shape create(String id) {
        try {
            return (Shape) factories
                    //map中没有该id，则put(id,ShapeFactory2::load计算的结果)，并返回计算结果
                    .computeIfAbsent(id, ShapeFactory2::load)
                    .newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建对象失败");
        }
    }

    public static void main(String[] args) {
        FactoryMethod factoryMethod = new ShapeFactory2();
        Shape shape = factoryMethod.create("Circle");
        shape.draw();
    }
}
